unit StockChart_Boll;

interface
            
uses
  StockChart,
  GR32,
  SysUtils,
  RuleEx_Boll;

type                
  PChartData_Boll   = ^TChartData_Boll;
  TChartData_Boll   = record
    Prev_X          : integer;
    Prev_Y          : Integer;
    Prev_Y_UB       : Integer;
    Prev_Y_LB       : Integer;
    Rule_Data       : TRule_Boll_Price;
    Color_1         : TColor32;
    Color_UB        : TColor32;
    Color_LB        : TColor32;
  end;
                
  TStockChart_Boll = class(TBaseStockChart)
  protected
    fChart_Data: TChartData_Boll;
  public
    constructor Create; override;
    destructor Destroy; override;
    procedure DrawChartItem(AChartPriceItem: PChartPriceItem); override;  
    property Rule_Data: TRule_Boll_Price read fChart_Data.Rule_Data write fChart_Data.Rule_Data;
  end;
  
  procedure DrawChart_Item_Price_Boll(AChartPriceItem: PChartPriceItem; AChartData: PChartData_Boll; ACoord: TChartCoord);
  
implementation

procedure DrawChart_Item_Price_Boll(AChartPriceItem: PChartPriceItem; AChartData: PChartData_Boll; ACoord: TChartCoord);
var
  tmpBollY: Integer;
  tmpBoll_UB_Y: Integer;
  tmpBoll_LB_Y: Integer;
begin
  if nil = AChartData.Rule_Data then
    exit;
  //------------------------------------------------------------------
  // draw boll line
  tmpBollY := ACoord.Position(Round(AChartData.Rule_Data.Boll[AChartPriceItem.ItemIndex]));
  tmpBoll_UB_Y := ACoord.Position(Round(AChartData.Rule_Data.UB[AChartPriceItem.ItemIndex]));
  tmpBoll_LB_Y := ACoord.Position(Round(AChartData.Rule_Data.LB[AChartPriceItem.ItemIndex]));
  if 0 = AChartData.Prev_X then
  begin
    AChartData.Prev_X := AChartPriceItem.ItemRect.Left + AChartPriceItem.ChartPrice.ChartItemWidthHalf;
  end else
  begin
    if IsValidChartPointY(AChartData.Prev_Y, AChartPriceItem.ChartPrice) and
       IsValidChartPointY(tmpBollY, AChartPriceItem.ChartPrice) then
    begin
      AChartPriceItem.ChartPrice.BackgroundBitmap.Line(
            AChartData.Prev_X, AChartData.Prev_Y,
            AChartPriceItem.ItemRect.Left + AChartPriceItem.ChartPrice.ChartItemWidthHalf, tmpBollY,
            clWhite32);
    end;
    if IsValidChartPointY(AChartData.Prev_Y_UB, AChartPriceItem.ChartPrice) and
       IsValidChartPointY(tmpBoll_UB_Y, AChartPriceItem.ChartPrice) then
    begin
      AChartPriceItem.ChartPrice.BackgroundBitmap.Line(
            AChartData.Prev_X, AChartData.Prev_Y_UB,
            AChartPriceItem.ItemRect.Left + AChartPriceItem.ChartPrice.ChartItemWidthHalf, tmpBoll_UB_Y,
            clYellow32);
    end;
    if IsValidChartPointY(AChartData.Prev_Y_LB, AChartPriceItem.ChartPrice) and
       IsValidChartPointY(tmpBoll_LB_Y, AChartPriceItem.ChartPrice) then
    begin
      AChartPriceItem.ChartPrice.BackgroundBitmap.Line(
            AChartData.Prev_X, AChartData.Prev_Y_LB,
            AChartPriceItem.ItemRect.Left + AChartPriceItem.ChartPrice.ChartItemWidthHalf, tmpBoll_LB_Y,
            clFuchsia32);
    end;
    AChartData.Prev_X := AChartPriceItem.ItemRect.Left + AChartPriceItem.ChartPrice.ChartItemWidthHalf;
  end;   
  AChartData.Prev_Y := tmpBollY;
  AChartData.Prev_Y_UB := tmpBoll_UB_Y;
  AChartData.Prev_Y_LB := tmpBoll_LB_Y;
end;

{ TStockChart_Boll }

constructor TStockChart_Boll.Create;
begin
  inherited;
  FillChar(fChart_Data, SizeOf(fChart_Data), 0);
  fBaseChartData.ChartCoord := TChartCoord.Create; 
end;

destructor TStockChart_Boll.Destroy;
begin
  if nil <> fBaseChartData.ChartCoord then
    FreeAndNil(fBaseChartData.ChartCoord);
  inherited;
end;

procedure TStockChart_Boll.DrawChartItem(AChartPriceItem: PChartPriceItem);
begin
  DrawChart_Item_Price_Boll(AChartPriceItem, @fChart_Data, fBaseChartData.ChartCoord);
end;

end.
